#pragma once
#include <iostream>
#include <ostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <stdarg.h>

#ifndef WIN32

#endif // !WIN32

#define NONE         "\033[m"
#define RED          "\033[0;32;31m"
#define LIGHT_RED    "\033[1;31m"
#define GREEN        "\033[0;32;32m"
#define LIGHT_GREEN  "\033[1;32m"
#define BLUE         "\033[0;32;34m"
#define LIGHT_BLUE   "\033[1;34m"
#define DARY_GRAY    "\033[1;30m"
#define CYAN         "\033[0;36m"
#define LIGHT_CYAN   "\033[1;36m"
#define PURPLE       "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN        "\033[0;33m"
#define YELLOW       "\033[1;33m"
#define LIGHT_GRAY   "\033[0;37m"
#define WHITE        "\033[1;37m"

#ifdef _DEBUG
	#define myprintf(color,format,...) printf(color format NONE,__VA_ARGS__)
	#define MyAssert(a) assert((a) == 0)
#else
	//#define myprintf(color,format,...) printf(color format NONE,__VA_ARGS__)
	#define MyAssert(a) a;
	#define myprintf(color,format,...)
#endif
#define dataprintf(format,...) myprintf(BLUE,"[DATA]:" format,__VA_ARGS__)
#define infoprintf(format,...) myprintf(WHITE,"[INFO]:" format,__VA_ARGS__)
#define warnprintf(format,...) myprintf(YELLOW,"[WARN]:" format,__VA_ARGS__)
#define errorprintf(format,...) myprintf(RED,"[ERROR]:" format,__VA_ARGS__)

enum MysqlDataType
{
	TINYINT,
	SMALLINT,
	MEDIUMINT,
	INT,
	BIGINT,
	FLOAT,
	DOUBLE,
	DECIMAL,
	DATE,
	TIME,
	TIME_MS,
	YEAR,
	DATETIME,
	DATETIME_MS,
	TIMESTAMP,
	CHAR,
	VARCHAR,
	TINYBLOB,
	TINYTEXT,
	BLOB,
	TEXT,
	MEDIUMBLOB,
	MEDIUMTEXT,
	LONGBLOB,
	LONGTEXT,
	UNDEFINED = -1
};

struct mydate
{
	mydate()
	{}
	mydate(int year_in, int month_in, int day_in)
	{
		year = year_in;
		month = month_in;
		day = day_in;
	}
	int year = 0, month = 0, day = 0;
	friend std::ostream& operator<<(std::ostream& out, const mydate& date)
	{
		out << date.year << '-' << date.month << '-' << date.day;
		return out;
	}
	std::string to_string()
	{
		char str[255] = { 0 };
		sprintf_s(str, 255, "'%04d-%02d-%02d'", year, month, day);
		return std::string(str);
	}
};

struct mytime
{
	mytime()
	{}
	mytime(int hour_in, int minute_in, int second_in)
	{
		hour = hour_in;
		minute = minute_in;
		second = second_in;
	}
	int hour = 0, minute = 0, second = 0;
	friend std::ostream& operator<<(std::ostream& out, const mytime& time)
	{
		out << time.hour << ':' << time.minute << ':' << time.second;
		return out;
	}
	std::string to_string()
	{
		char str[255] = { 0 };
		sprintf_s(str, 255, "'%02d:%02d:%02d'", hour, minute, second);
		return std::string(str);
	}
};

struct mytime_ms
{
	mytime_ms() {}
	mytime_ms(int hour_in, int minute_in, int second_in, int millisecond_in)
	{
		hour = hour_in;
		minute = minute_in;
		second = second_in;
		millisecond = millisecond_in;
	}
	int hour = 0, minute = 0, second = 0, millisecond = 0;
	friend std::ostream& operator<<(std::ostream& out, const mytime_ms& time)
	{
		out << time.hour << ':' << time.minute << ':' << time.second << '.' << time.millisecond;
		return out;
	}
	std::string to_string()
	{
		char str[255] = { 0 };
		sprintf_s(str, 255, "'%02d:%02d:%02d.%03d'", hour, minute, second, millisecond);
		return std::string(str);
	}
};

struct mydatetime
{
	mydate date;
	mytime time;
	mydatetime()
	{}
	mydatetime(mydate date_in,mytime time_in)
	{
		date = date_in;
		time = time_in;
	}

	friend std::ostream& operator<<(std::ostream& out, const mydatetime& datetime)
	{
		out << datetime.date << ' ' << datetime.time;
		return out;
	}
	std::string to_string()
	{
		std::string date_str = date.to_string();
		date_str.pop_back();//pop_back the last "'"
		std::string time_str = time.to_string();
		time_str.erase(time_str.begin());//erase the first "'"
		return date_str + " " + time_str;
	}
};

struct mydatetime_ms
{
	mydate date;
	mytime_ms time;
	mydatetime_ms()
	{}
	mydatetime_ms(mydate date_in, mytime_ms time_in)
	{
		date = date_in;
		time = time_in;
	}
	friend std::ostream& operator<<(std::ostream& out, const mydatetime_ms& datetime)
	{
		out << datetime.date << ' ' << datetime.time;
		return out;
	}
	std::string to_string()
	{
		std::string date_str = date.to_string();
		date_str.pop_back();//pop_back the last "'"
		std::string time_str = time.to_string();
		time_str.erase(time_str.begin());//erase the first "'"
		return date_str + " " + time_str;
	}
};